home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
225
/
mymenu
/
dorun.c
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
11KB
|
432 lines
/* Copyright ) Darin Johnson, 1989 */
/* DoRun.c -- I met her on a Monday, and my heart stood still... */
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <functions.h>
#include "mymenu.h"
#ifdef AZTEC_C
#define strlen _BUILTIN_strlen
#define strcpy _BUILTIN_strcpy
#endif
#ifdef DO_PATH
#define CMDSIZ 256
#define CBUFSZ 80
#endif
extern struct Process *MyProcess;
/* text to put into autorequesters */
struct IntuiText err_nocmd = { 0,1,JAM2, 20,10, NULL,
(UBYTE*)"MyMenu: can't execute command", NULL };
struct IntuiText err_nomem = { 0,1,JAM2, 20,10, NULL,
(UBYTE*)"MyMenu: out of memory!", NULL };
struct IntuiText err_noinfo = { 0,1,JAM2, 20,10, NULL,
(UBYTE*)"MyMenu: can't open info file", NULL };
struct IntuiText err_notool = { 0,1,JAM2, 20,10, NULL,
(UBYTE*)"MyMenu: not a tool or project", NULL };
struct IntuiText req_neg = { 0,1,JAM2, 7,3, NULL,
(UBYTE*)"Aw, shucks", NULL };
/* process a menu item */
int run_item(item)
struct ext_MenuItem *item;
{
if (item->cmd) {
if (item->type == 'C') {
do_clirun(item->cmd, item->args);
}
#ifdef DO_WB
else if (item->type == 'W') {
do_wbrun(item->cmd);
}
#endif
}
}
#ifdef DO_PATH
char *FindIt();
#endif
/* execute a CLI command */
do_clirun(cmd, args)
char *cmd, *args;
{
struct FileHandle *NilFh, *Open();
register char *buf;
register short siz;
#ifdef DO_PATH
cmd = FindIt(cmd);
#endif
if (cmd==NULL) {
AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
return;
}
siz = 32 + strlen(cmd);
if (args)
siz += strlen(args);
buf = (char *)AllocMem(siz, MEMF_PUBLIC);
if (buf==NULL) {
AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
return;
}
strcpy(buf, "RUN <NIL: >NIL: \"");
strcat(buf, cmd);
strcat(buf, "\" <NIL: >NIL: ");
if (args)
strcat(buf, args);
NilFh = Open("NIL:", MODE_NEWFILE);
if (NilFh) {
Execute(buf, NULL, NilFh);
Close(NilFh);
}
FreeMem(buf, siz);
}
/* procedures to support running WorkBench programs */
#ifdef DO_WB
extern int wb_cnt;
extern struct MsgPort *wb_reply_port;
/* create (and allocate) a copy of a string */
char *copystr(str) {
char *tmpstr;
if (!str)
return NULL;
tmpstr = (char *)AllocMem(strlen(str)+1, MEMF_PUBLIC);
strcpy(tmpstr, str);
return tmpstr;
}
/* Free up space used by a workbench startup message. Called whenever
a workbench program replies to the startup message, and whenever
do_wbrun() gets an error */
wbfree(WBStartup)
struct WBStartup *WBStartup;
{
register BPTR lock;
register int i;
register char *cp;
if (WBStartup != NULL) {
if (WBStartup->sm_ArgList != NULL) {
for (i=0; i<WBStartup->sm_NumArgs; i++) {
if ((lock=WBStartup->sm_ArgList[i].wa_Lock) != NULL) {
UnLock(lock);
}
if ((cp=WBStartup->sm_ArgList[i].wa_Name) != NULL)
FreeMem(cp, strlen(cp)+1);
}
FreeMem(WBStartup->sm_ArgList,
sizeof(struct WBArg)*WBStartup->sm_NumArgs);
}
if (WBStartup->sm_Segment != NULL) {
UnLoadSeg(WBStartup->sm_Segment);
}
if ((cp=WBStartup->sm_ToolWindow) != NULL)
FreeMem(cp, strlen(cp)+1);
FreeMem(WBStartup, sizeof(struct WBStartup));
}
}
/* take the path passed, and split it into a lock and name,
suitable for putting into a WBArg structure */
split_path(path, dir_lock, name)
char *path, **name;
BPTR *dir_lock;
{
register char *p;
register BPTR lock;
for (p=path, *name=path; *p; p++)
if (*p == '/' || *p == ':')
*name = p+1;
lock = (BPTR)Lock(path, ACCESS_READ);
if (lock) {
*dir_lock = (BPTR)ParentDir(lock);
UnLock(lock);
} else {
*dir_lock = (BPTR)DupLock(MyProcess->pr_CurrentDir);
}
}
/* load and run a workbench program */
int do_wbrun(cmd)
char *cmd;
{
BPTR lock, oldlock;
struct WBStartup *WBStartup;
struct DiskObject *disk_object;
char argc, *name, buf[128];
char error;
disk_object = WBStartup = NULL;
lock = oldlock = NULL;
name = NULL;
error = TRUE; /* assume the worst */
/* allocate the startup message */
if ((WBStartup = (struct WBStartup *)AllocMem(sizeof(struct WBStartup),
MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
return TRUE; /* don't go to finish:, nothing allocated yet */
}
#ifdef DO_PATH
if ((cmd = FindIt(cmd)) == NULL)
goto finish;
#endif
/* find the directory and name of the program to run */
split_path(cmd, &lock, &name);
if (lock == NULL) {
AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
goto finish;
}
/* try to load in the .info file */
oldlock = (BPTR)CurrentDir(lock);
if ((disk_object = GetDiskObject(name)) == NULL) {
AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
goto finish;
}
/* allocate the WBArgs - if we are a tool, we allocate one */
/* of these, else two (one for tool, one for project) */
if (disk_object->do_Type == WBTOOL) {
if ((WBStartup->sm_ArgList = (struct WBArg *)
AllocMem(sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
goto finish;
}
WBStartup->sm_NumArgs = 1;
} else if (disk_object->do_Type == WBPROJECT) {
if ((WBStartup->sm_ArgList = (struct WBArg *)
AllocMem(sizeof(struct WBArg)*2, MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
goto finish;
}
WBStartup->sm_NumArgs = 2;
/* fill in arg #2 with the info we already have */
WBStartup->sm_ArgList[1].wa_Lock = (BPTR)lock;
WBStartup->sm_ArgList[1].wa_Name = copystr(name);
/* now find the tool */
strcpy(buf, disk_object->do_DefaultTool);
split_path(buf, &lock, &name);
FreeDiskObject(disk_object);
CurrentDir(lock);
if ((disk_object = GetDiskObject(name)) == NULL) {
AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
goto finish;
}
/* we have to have a tool at this point - or else */
if (disk_object->do_Type != WBTOOL) {
AutoRequest(NULL, &err_notool, NULL, &req_neg, 0,0,300,60);
goto finish;
}
}
/* fill in arguments */
WBStartup->sm_ArgList[0].wa_Lock = (BPTR)lock;
WBStartup->sm_ArgList[0].wa_Name = copystr(name);
/* initialize rest of startup message */
WBStartup->sm_Message.mn_ReplyPort = wb_reply_port;
WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup);
WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
WBStartup->sm_ToolWindow = copystr(disk_object->do_ToolWindow);
/* get a decent stack size, there are a few progs that set this to zero */
if (disk_object->do_StackSize < 4000)
disk_object->do_StackSize = 4000;
/* load in the program */
if ((WBStartup->sm_Segment = (BPTR)LoadSeg(name)) == NULL) {
AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
goto finish;
}
/* create process */
if ((WBStartup->sm_Process = (struct MsgPort *)CreateProc(name,
0, WBStartup->sm_Segment, disk_object->do_StackSize)) == NULL) {
AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
goto finish;
}
/* everything's ok -- start 'er up */
PutMsg(WBStartup->sm_Process, WBStartup);
error = FALSE;
wb_cnt++; /* keep track of unreplied startup messages */
finish:
if (disk_object) FreeDiskObject(disk_object);
if (oldlock) CurrentDir(oldlock);
if (error)
wbfree(WBStartup);
return error;
}
#endif
#ifdef DO_PATH
/* This section is largely taken from RunBack
(which was largely taken from which.c by Carolyn Scheppner).
This handles path searching.
*/
/***** currently these routines can cause guru's
Run a workbench program, and then run a program that
uses the path searching - often causes a Guru, but can't
tell why. If the wbfree() does NOT free its locks, then
it doesn't guru.
*****/
static char sbuf[CMDSIZ];
/* search for a command in our path */
char *FindIt(command)
char *command;
{
BOOL getPath();
struct Path *path;
struct FileInfoBlock *fib;
BPTR lock, startcd;
BOOL Found, InitialCD;
/* Were we given full path in command name (':' in name) ? */
{
register char *p;
for (p=command; *p; p++) {
if (*p == ':') {
lock = (BPTR)Lock(command,ACCESS_READ);
if (lock==NULL)
return NULL; /* command not found */
UnLock(lock);
return command;
}
}
}
/* allocate this for Examine() calls */
fib = (struct FileInfoBlock *)
AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR);
if (fib == NULL)
return NULL;
/* Check current directory */
Found = getPath(command, fib, sbuf);
/* Check along paths */
if (!Found) {
InitialCD = TRUE;
for (path = MM->CLI_path; (path) && (!Found); path = path->path_Next) {
/* CD to each path */
lock = (BPTR)CurrentDir(path->path_Lock);
if (InitialCD) {
startcd = lock; InitialCD = FALSE;
}
/* See if command is there */
Found = getPath(command, fib, sbuf);
}
/* If we CD'd anywhere, restore initial CD */
if (!InitialCD)
CurrentDir(startcd);
}
/* Check C: */
if (!Found) {
char cbuf[CBUFSZ];
strcpy(cbuf,"C:");
strcpy(&cbuf[2], command);
Found = getPath(cbuf, fib, sbuf);
}
/* Free fib */
if (fib != NULL)
FreeMem(fib, sizeof(struct FileInfoBlock));
if (Found)
return(sbuf);
else
return(NULL);
}
/* see if command is in current directory, if so, return path name
in 'buf' */
BOOL
getPath(command,fib,buf)
char *command;
struct FileInfoBlock *fib;
char *buf;
{
BPTR lock;
BOOL success = FALSE;
if (lock = (BPTR)Lock(command, ACCESS_READ)) {
if (Examine(lock, fib)) {
buildPath(lock, fib, buf);
success = TRUE;
}
UnLock(lock);
}
return(success);
}
/* builds up a path name from 'inlock' and returns it in 'buf' */
buildPath(inlock,fib,buf)
BPTR inlock;
struct FileInfoBlock *fib;
char *buf;
{
int i;
BPTR lock, oldlock;
buf[0] = NULL;
lock = inlock;
/* follow path up, building up name as we go */
while (lock) {
if (Examine(lock, fib)) {
if (fib->fib_FileName[0] > ' ') {
if (buf[0]) insert(buf,"/");
insert(buf,fib->fib_FileName);
}
}
oldlock = lock;
lock = (BPTR)ParentDir(lock);
/* make sure we don't unlock the lock passed to us */
if (oldlock != inlock)
UnLock(oldlock);
}
/* fix up path name */
if (fib->fib_FileName[0] > ' ') {
register char *p;
for (p=buf; *p; p++) {
if (*p == '/') {
*p = ':';
break;
}
}
} else
insert(buf,"RAM:"); /* why? */
}
/* insert 's' at the beginning of 'buf' */
insert(buf,s)
char *buf,*s;
{
char tmp[CMDSIZ];
strcpy(tmp, buf);
strcpy(buf, s);
strcpy(&buf[strlen(s)], tmp);
}
#endif